import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/Addons.js";
import GUI from "lil-gui";
const gui = new GUI();

//加载纹理
//声明加载器实例
const textureLoader = new THREE.TextureLoader();
//加载器加载纹理，参数是图片路径
//颜色纹理
const colorTexture = textureLoader.load("src/assets/textures/door/color.jpg");
//透明纹理
const alphaTexture = textureLoader.load("src/assets/textures/door/alpha.jpg");
const heightTexture = textureLoader.load("src/assets/textures/door/height.jpg");
const normalTexture = textureLoader.load("src/assets/textures/door/normal.jpg");
//环境光遮蔽
const ambientOcclusionTexture = textureLoader.load(
  "src/assets/textures/door/ambientOcclusion.jpg"
);
//金属性
const metalnessTexture = textureLoader.load(
  "src/assets/textures/door/metalness.jpg"
);
//粗糙度
const roughnessTexture = textureLoader.load(
  "src/assets/textures/door/roughness.jpg"
);
const matcapsTexture = textureLoader.load("src/assets/textures/matcaps/3.png");
//渐变
const gradientsTexture = textureLoader.load(
  "src/assets/textures/gradients/3.jpg"
);
gradientsTexture.magFilter = THREE.NearestFilter;
gradientsTexture.minFilter = THREE.NearestFilter;
gradientsTexture.generateMipmaps = false;
const sizes = {
  width: window.innerWidth,
  height: window.innerHeight,
};

//监听窗口变化事件
window.addEventListener("resize", () => {
  //   console.log(window.innerWidth);
  sizes.width = window.innerWidth;
  sizes.height = window.innerHeight;

  //调整相机
  camera.aspect = sizes.width / sizes.height;
  camera.updateProjectionMatrix(); //更新相机

  //调整渲染器
  renderer.setSize(sizes.width, sizes.height);
  renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
});

//创建第一个场景
const scene = new THREE.Scene();

const group = new THREE.Group();
scene.add(group);

//添加光源--环境光
const ambientLight = new THREE.AmbientLight(0x404040, 0.5);
scene.add(ambientLight);

//创建一个点光源
const pointLight = new THREE.PointLight(0xffffff, 50);
pointLight.position.x = 2;
pointLight.position.y = 3;
pointLight.position.z = 4;

scene.add(pointLight);

const pointHelp = new THREE.PointLightHelper(pointLight);
scene.add(pointHelp);

//创建物体

//基础网格反射材质
// const material = new THREE.MeshLambertMaterial();

//增强光反射材质
// const material = new THREE.MeshPhongMaterial();
// material.shininess = 100;
// material.specular = new THREE.Color("red");

//网格卡通材质
// const material = new THREE.MeshToonMaterial();
// material.gradientMap = gradientsTexture;

//标准网格材质
// const material = new THREE.MeshStandardMaterial();
// material.roughness = 0.65;
// material.metalness = 0.55;
// material.map = colorTexture;
// material.aoMap = ambientOcclusionTexture;
// material.aoMapIntensity = 10;
// //置换贴图
// material.displacementMap = heightTexture;
// material.displacementScale = 0.05;

// //金属贴图
// material.metalnessMap = metalnessTexture;

// //粗糙度贴图
// material.roughnessMap = roughnessTexture;

// //法线贴图
// material.normalMap = normalTexture;
// material.normalScale.set(0.5, 0.6);

// //alpha贴图
// material.transparent = true;
// material.alphaMap = alphaTexture;
// material.opacity = 1;

//网格物理材质
// const material = new THREE.MeshPhysicalMaterial();

//点材质
// const material = new THREE.PointsMaterial();

// const material = new THREE.ShaderMaterial();

//用标准网格材质展示环境贴图
//加载环境贴图需要特定的加载器
const cubeTextureLoader = new THREE.CubeTextureLoader();
const environmentMap = cubeTextureLoader.load([
  "src/assets/textures/environmentMap/Standard-Cube-Map/px.png",
  "src/assets/textures/environmentMap/Standard-Cube-Map/nx.png",
  "src/assets/textures/environmentMap/Standard-Cube-Map/py.png",
  "src/assets/textures/environmentMap/Standard-Cube-Map/ny.png",
  "src/assets/textures/environmentMap/Standard-Cube-Map/pz.png",
  "src/assets/textures/environmentMap/Standard-Cube-Map/nz.png",
]);
const material = new THREE.MeshStandardMaterial();
material.roughness = 0.7;
material.metalness = 0.2;
material.envMap = environmentMap;
//球体
const sphere = new THREE.Mesh(new THREE.SphereGeometry(0.5, 16, 16), material);
sphere.position.x = -3;
console.log(sphere.geometry.attributes.normal);
sphere.geometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(sphere.geometry.attributes.uv.array, 2)
);

group.add(sphere);

//平面
const plane = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), material);
plane.position.x = 0;

plane.geometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(plane.geometry.attributes.uv.array, 2)
);
group.add(plane);

//圆环体
const tours = new THREE.Mesh(
  new THREE.TorusGeometry(0.3, 0.2, 16, 32),
  material
);
tours.position.x = 3;
tours.geometry.setAttribute(
  "uv2",
  new THREE.BufferAttribute(tours.geometry.attributes.uv.array, 2)
);
group.add(tours);

//创建摄像机
const camera = new THREE.PerspectiveCamera(60, sizes.width / sizes.height);
//相机位置
camera.position.z = 5;

camera.lookAt(group.position);

// 将相机加入场景
scene.add(camera);

//创建渲染器材
const renderer = new THREE.WebGLRenderer();
renderer.setSize(sizes.width, sizes.height);
document.body.appendChild(renderer.domElement);

//控制器
//两个参数 要控制的相机 参考点--一般是渲染的画布
const controls = new OrbitControls(camera, renderer.domElement);
// 如果开启了阻尼，需要每帧都更新控制器
controls.enableDamping = true;

//gui调试器
// 我们主要调试金属度和粗糙度
gui.add(material, "metalness").min(0).max(1).step(0.001);
gui.add(material, "roughness").min(0).max(1).step(0.001);
// gui.add(material, "aoMapIntensity").min(0).max(100).step(1);

const clock = new THREE.Clock();

const change = () => {
  let elapsedTime = clock.getElapsedTime();
  sphere.rotation.y = 0.1 * elapsedTime;
  plane.rotation.y = 0.1 * elapsedTime;
  tours.rotation.y = 0.1 * elapsedTime;

  sphere.rotation.x = 0.15 * elapsedTime;
  plane.rotation.x = 0.15 * elapsedTime;
  tours.rotation.x = 0.15 * elapsedTime;

  controls.update();
  renderer.render(scene, camera);
  window.requestAnimationFrame(change);
};
change();
